package org.dtrd.modules.control.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.common.util.CheckUtil;
import org.dtrd.common.util.DateUtils;
import org.dtrd.common.util.StringUtil;
import org.dtrd.config.system.Constant;
import org.dtrd.config.system.Constant.TargetProject;
import org.dtrd.modules.archive.entity.bean.SchemeInputBean;
import org.dtrd.modules.archive.entity.po.*;
import org.dtrd.modules.archive.service.*;
import org.dtrd.modules.control.entity.bean.PatientTargetReachStandardAvgRateDaily;
import org.dtrd.modules.control.entity.bean.TargetAndDetailInfo;
import org.dtrd.modules.control.entity.bean.TargetAndDetailInfo.TargetAndDetailInfoBuilder;
import org.dtrd.modules.control.entity.bean.TargetInfo;
import org.dtrd.modules.control.entity.po.DtrdEntRdSigninTarget;
import org.dtrd.modules.control.entity.po.DtrdEntRdSigninTargetDetail;
import org.dtrd.modules.control.entity.request.TargetPageRequest;
import org.dtrd.modules.control.mapper.DtrdEntRdSigninTargetMapper;
import org.dtrd.modules.control.service.IDtrdEntRdSigninTargetDetailService;
import org.dtrd.modules.control.service.IDtrdEntRdSigninTargetService;
import org.dtrd.modules.archive.entity.po.DtrdEntRdArchiveBasic;
import org.dtrd.modules.archive.service.IDtrdEntRdArchiveBasicService;
import org.dtrd.modules.util.SchemeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 *
 */
@Service
@Slf4j
@DS("multi-datasource1")
public class DtrdEntRdSigninTargetServiceImpl extends ServiceImpl<DtrdEntRdSigninTargetMapper, DtrdEntRdSigninTarget> implements IDtrdEntRdSigninTargetService {

    @Autowired
    private IDtrdEntRdSigninTargetDetailService targetDetailService;

    @Autowired
    private IDtrdEntRdComplicationService complicationService;

    @Autowired
    private IDtrdEntRdComorbidityService comorbidityService;

    @Autowired
    private IDtrdEntRdLaboratoryService laboratoryService;

    @Autowired
    private IDtrdEntRdArchiveBasicService basicService;

    @Autowired
    private IDtrdEntRdPhysicalService physicalService;

    @Autowired
    private IDtrdEntRdOverviewService overviewService;

    @Autowired
    private IDtrdEntRdAnamnesisService anamnesisService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdateTargetAndDetail(TargetAndDetailInfo requestInfo) {
        Integer patientId = requestInfo.getPatientId();
        // 更新或保存 targetDetail
        Integer targetId = saveControlTarget(requestInfo);
        // 存 targetDetail 记录
        targetDetailService.removeTargetDetails(targetId);
        List<DtrdEntRdSigninTargetDetail> targetDetails = requestInfo.toTargetDetailList();
        for (DtrdEntRdSigninTargetDetail targetDetail : targetDetails) {
            targetDetail.buildWithParams(patientId, targetId);
            Integer projectType = targetDetail.getProjectType();
            LambdaUpdateWrapper<DtrdEntRdSigninTargetDetail> updateWrapper = Wrappers.lambdaUpdate(DtrdEntRdSigninTargetDetail.class)
                    .eq(DtrdEntRdSigninTargetDetail::getPatientId, patientId).eq(DtrdEntRdSigninTargetDetail::getTargetId, targetId).eq(DtrdEntRdSigninTargetDetail::getProjectType, projectType);
            targetDetailService.saveOrUpdate(targetDetail, updateWrapper);
        }
        return true;
    }

    private Integer saveControlTarget(TargetAndDetailInfo requestInfo) {
        // 更新或保存 target
        DtrdEntRdSigninTarget target = new DtrdEntRdSigninTarget();
        if (requestInfo.getTargetId() == null) {
            // 新增时状态设置成使用中
            target.setCurrentStatus(Constant.TargetStatus.USING.getType());
            // 禁用掉上一条记录
            changeLatestTargetStatus(requestInfo.getPatientId());
            target = target.init();
        }
        target = target.parseFromDTO(requestInfo);
        saveOrUpdate(target);
        return target.getDataId();
    }

    @Override
    public void saveControlTarget(Integer patientId, Integer packageId, String packageName, Date serviceStartTime) {
        String endDate = DateUtils.dateAdd(7, serviceStartTime);
        TargetAndDetailInfo build = TargetAndDetailInfoBuilder.aTargetAndDetailInfo().withTargetName(packageName + "控制目标 ").withPatientId(patientId).withStartDate(serviceStartTime).withEndDate(DateUtils.str2Date(endDate, DateUtils.date_sdf.get())).build();
        Integer targetId = saveControlTarget(build);
        if (targetId == 0) {
            // 保存控制目标失败
            return;
        }
        SchemeInputBean result = handlePatientInfo(patientId);
        log.info("DtrdEntRdSigninTargetServiceImpl.saveControlTarget.[patientId, packageId, packageName, serviceStartTime] patientId= " + patientId + "; result=" + result);
        float bmi = SchemeUtil.getBmi(result.getHeight(), result.getWeight());
        // 实际值（从档案中取得）
        // 合并症
        boolean comorbidity = result.isComorbidity();
        // 并发症
        boolean complication = result.isComplication();
        // 低血糖
        boolean bloodSugarLow = result.isBloodSugarLow();
        // 合并冠心病
        boolean coronaryDisease = result.isCoronaryDisease();
        // 舒张压/低压
        // 收缩压/高压
        List<DtrdEntRdSigninTargetDetail> list = new ArrayList<>(10);
        // 1-体质指数（BMI）
        list.add(handleBmiTargetDetail(bmi, targetId));
        // 糖化
        list.add(handleHba1cTargetDetail(result.getHba1c(), comorbidity, complication, bloodSugarLow, targetId));
        // 3-空腹血糖（FBG）
        list.add(handleFbgTargetDetail(result.getFbgVal(), targetId));
        // 餐后血糖
        list.add(handlePbgTargetDetail(result.getPbgVal(), targetId));
        // 血压
        list.addAll(handleBloodPressureTargetDetail(result.getLbpVal(), result.getHbpVal(), result.getAge(), targetId));
        //总胆固醇 TC
        list.add(handleTcTargetDetail(result.getTcVal(), targetId));
        //  8-甘油三酯（TG）
        list.add(handleTgTargetDetail(result.getTgVal(), targetId));
        // 高密度脂蛋白
        list.add(handleHdlTargetDetail(result.getHdlVal(), StringUtil.StrTrimInt(result.getGender()), targetId));
        // 低密度脂蛋白
        list.add(handleLdlTargetDetail(result.getLdlVal(), coronaryDisease, targetId));
        targetDetailService.saveBatch(list);
    }

    private DtrdEntRdSigninTargetDetail handleBmiTargetDetail(Float targetValue, Integer targetId) {
        float bmiLow = 18.5f;
        float bmiHigh = 24f;
        String resultStr = "";
        if (0 == targetValue) {
        } else if (targetValue < bmiLow) {
            resultStr = "消瘦";
        } else if (targetValue >= bmiHigh && targetValue < 28) {
            resultStr = "超重";
        } else if (targetValue >= 28) {
            resultStr = "肥胖";
        } else {
            resultStr = "正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(bmiLow, bmiHigh, targetValue, TargetProject.BMI.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handleHba1cTargetDetail(Float targetValue, boolean comorbidity, boolean complication, boolean bloodSugarLow, Integer targetId) {
        float hba1cComHigh = 6.5f;
        float hba1cHigh = 7f;
        String resultStr = "";
        float tmpHba1cHigh = hba1cComHigh;
        if (!(comorbidity && complication && bloodSugarLow)) {
            tmpHba1cHigh = hba1cHigh;
        }
        if (0 == targetValue) {
        } else if (targetValue > tmpHba1cHigh) {
            resultStr = "糖化血红蛋白不达标";
        } else {
            resultStr = "糖化血红蛋白正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(0f, tmpHba1cHigh, targetValue, TargetProject.HBA1C.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handleFbgTargetDetail(Float targetValue, Integer targetId) {
        float fbgLow = 4.4f;
        float fbgHigh = 7f;
        String resultStr = "";
        if (0 == targetValue) {
        } else if (targetValue < fbgLow) {
            resultStr = "空腹血糖偏低";
        } else if (targetValue > fbgHigh) {
            resultStr = "空腹血糖偏高";
        } else {
            resultStr = "空腹血糖正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(fbgLow, fbgHigh, targetValue, TargetProject.FBG.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handlePbgTargetDetail(Float targetValue, Integer targetId) {
        float targetLow = 4.4f;
        float targetHigh = 10f;
        String resultStr = "";
        if (0 == targetValue) {
        } else if (targetValue < targetLow) {
            resultStr = "餐后血糖偏低";
        } else if (targetValue > targetHigh) {
            resultStr = "餐后血糖偏高";
        } else {
            resultStr = "餐后血糖正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(targetLow, targetHigh, targetValue, TargetProject.FBG.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handleTcTargetDetail(Float targetValue, Integer targetId) {
        float tcLow = 2.84f;
        float tcHigh = 4.5f;
        String resultStr = "";
        if (0 == targetValue) {
        } else if (targetValue < tcLow) {
            resultStr = "总胆固醇偏低";
        } else if (targetValue > tcHigh) {
            resultStr = "总胆固醇偏高";
        } else {
            resultStr = "总胆固醇正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(tcLow, tcHigh, targetValue, TargetProject.TC.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handleTgTargetDetail(Float targetValue, Integer targetId) {
        float tgLow = 0.56f;
        float tgHigh = 1.7f;
        String resultStr = "";
        if (0 == targetValue) {
        } else if (targetValue < tgLow) {
            resultStr = "甘油三酯偏低";
        } else if (targetValue > tgHigh) {
            resultStr = "甘油三酯偏高";
        } else {
            resultStr = "甘油三酯正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(tgLow, tgHigh, targetValue, TargetProject.TC.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handleHdlTargetDetail(Float targetValue, Integer gender, Integer targetId) {
        float hdlMaleLow = 1f;
        float hdlMaleHigh = 1.76f;
        float hdlFemaleLow = 1.3f;
        float hdlFemaleHigh = 1.76f;
        float tmpHdlLow = hdlFemaleLow;
        float tmpHdlHigh = hdlFemaleHigh;
        if (1 == gender) {
            tmpHdlLow = hdlMaleLow;
            tmpHdlHigh = hdlMaleHigh;
        }
        String resultStr = "";
        if (0 == targetValue) {
        } else if (targetValue < tmpHdlLow) {
            resultStr = "高密度脂蛋白偏低";
        } else if (targetValue > tmpHdlHigh) {
            resultStr = "高密度脂蛋白偏高";
        } else {
            resultStr = "高密度脂蛋白正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(tmpHdlLow, tmpHdlHigh, targetValue, TargetProject.TC.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private DtrdEntRdSigninTargetDetail handleLdlTargetDetail(Float targetValue, boolean coronaryDisease, Integer targetId) {
        float ldlComHigh = 2.6f;
        float ldlHigh = 1.8f;
        String resultStr = "";
        float tmpLdlHigh = ldlHigh;
        if (coronaryDisease) {
            tmpLdlHigh = ldlComHigh;
        }
        if (0 == targetValue) {
        } else if (targetValue > tmpLdlHigh) {
            resultStr = "低密度脂蛋白偏高";
        } else {
            resultStr = "低密度脂蛋白正常";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(0f, tmpLdlHigh, targetValue, TargetProject.TC.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        return detail;
    }

    private List<DtrdEntRdSigninTargetDetail> handleBloodPressureTargetDetail(Float lbpVal, Float hbpVal, int age, Integer targetId) {
        float lbpLow = 60;
        float lbpHigh = 80;
        float hbpLow = 90;
        float hbpHigh = 130;
        float lbpLow65 = 60;
        float lbpHigh65 = 90;
        float hbpLow65 = 90;
        float hbpHigh65 = 150;
        float tmpLbpLow = lbpLow;
        float tmpLbpHigh = lbpHigh;
        float tmphbpLow = hbpLow;
        float tmphbpHigh = hbpHigh;
        if (age > 65) {
            tmpLbpLow = lbpLow65;
            tmpLbpHigh = lbpHigh65;
            tmphbpLow = hbpLow65;
            tmphbpHigh = hbpHigh65;
        }
        String resultStr = null;
        if (0 == lbpVal || 0 == hbpVal) {
        } else if (lbpVal <= tmpLbpLow && hbpVal <= tmphbpLow) {
            resultStr = "血压偏低";
        } else if (lbpVal <= tmpLbpLow && (hbpVal > tmphbpLow && hbpVal < tmphbpHigh)) {
            resultStr = "血压偏低";
        } else if (lbpVal <= tmpLbpLow && hbpVal >= tmphbpHigh) {
            resultStr = "血压偏高";
        } else if ((lbpVal > tmpLbpLow && lbpVal < tmpLbpHigh) && hbpVal <= tmphbpLow) {
            resultStr = "血压偏低";
        } else if ((lbpVal > tmpLbpLow && lbpVal < tmpLbpHigh) && (hbpVal > tmphbpLow && hbpVal < tmphbpHigh)) {
            resultStr = "血压正常";
        } else if ((lbpVal > tmpLbpLow && lbpVal < tmpLbpHigh) && hbpVal >= tmphbpHigh) {
            resultStr = "血压偏高";
        } else if (lbpVal >= tmpLbpHigh && hbpVal <= tmphbpLow) {
            resultStr = "血压偏高";
        } else if (lbpVal >= tmpLbpHigh && (hbpVal > tmphbpLow && hbpVal < tmphbpHigh)) {
            resultStr = "血压偏高";
        } else if (lbpVal >= tmpLbpHigh && hbpVal >= tmphbpHigh) {
            resultStr = "血压偏高";
        }
        DtrdEntRdSigninTargetDetail detail = generateTargetDetail(tmpLbpLow, tmpLbpHigh, lbpVal, TargetProject.PRESSURE_LOW.getType());
        detail.setResult(resultStr);
        detail.setTargetId(targetId);
        DtrdEntRdSigninTargetDetail detail2 = generateTargetDetail(tmphbpLow, tmphbpHigh, hbpVal, TargetProject.PRESSURE_HIGH.getType());
        detail2.setResult(resultStr);
        detail2.setTargetId(targetId);
        List<DtrdEntRdSigninTargetDetail> list = new ArrayList<>(2);
        list.add(detail);
        list.add(detail2);
        return list;
    }

    private DtrdEntRdSigninTargetDetail generateTargetDetail(Float targetLow, Float targetHigh, Float targetValue, Integer projectType) {
        DtrdEntRdSigninTargetDetail targetDetail = new DtrdEntRdSigninTargetDetail();
        targetDetail.setTargetLow(targetLow);
        targetDetail.setTargetHigh(targetHigh);
        targetDetail.setValue(targetValue);
        targetDetail.setProjectType(projectType);
        return targetDetail;
    }

    /**
     * 处理患者档案相关信息
     *
     * @param patientId
     * @return
     */
    private SchemeInputBean handlePatientInfo(Integer patientId) {
        SchemeInputBean result = new SchemeInputBean();
        // 基本信息
        handleBaseInfo(patientId, result);
        // 实验室检查表
        handleLaboratoryInfo(patientId, result);
        // 体格检查表
        handlePhysicalInfo(patientId, result);
        // 糖尿病概况
        handleOverview(patientId, result);
        // 既往病史
        handleAnamnesis(patientId, result);
        // 合并症
        handleComorbidity(patientId, result);
        // 并发症
        handleComplication(patientId, result);
        return result;
    }

    /**
     * 并发症
     *
     * @param patientId
     * @param result
     */
    private void handleComplication(Integer patientId, SchemeInputBean result) {
//        // 糖尿病肾病
//        // 糖尿病视网膜病变
//        // 糖尿病周围神经病变（远端对称性多神经病变）
//        // 心血管自主神经病变
//        // 消化系统自主神经病变
//        // 泌尿生殖系统自主神经病变
//        // 其他自主神经病变
//        // 糖尿病下肢血管病变
//        // 糖尿病足
//        // 酮症酸中毒（DKA）
//        // 糖尿病高渗综合症（HHS）
        DtrdEntRdArchiveComplication complicationVO = complicationService.getPatientDiabetesComplication(patientId);
        if (null != complicationVO) {
            if (1 == StringUtil.StrTrimInt(complicationVO.getNephropathy()) || 1 == StringUtil.StrTrimInt(complicationVO.getRetinopathy()) || 1 == StringUtil.StrTrimInt(complicationVO.getPeripheral()) || 1 == StringUtil.StrTrimInt(complicationVO.getCardiovascular()) || 1 == StringUtil.StrTrimInt(complicationVO.getDigestive()) || 1 == StringUtil.StrTrimInt(complicationVO.getGenitourinary()) || 1 == StringUtil.StrTrimInt(complicationVO.getOtherneuropathy()) || 1 == StringUtil.StrTrimInt(complicationVO.getExtremity()) || 1 == StringUtil.StrTrimInt(complicationVO.getDfoot()) || 1 == StringUtil.StrTrimInt(complicationVO.getDka()) || 1 == StringUtil.StrTrimInt(complicationVO.getHhs())) {
                result.setComplication(true);
            } else {
                result.setComplication(false);
            }
            // 是否神经病变
            if (1 == StringUtil.StrTrimInt(complicationVO.getPeripheral()) || 1 == StringUtil.StrTrimInt(complicationVO.getCardiovascular()) || 1 == StringUtil.StrTrimInt(complicationVO.getDigestive()) || 1 == StringUtil.StrTrimInt(complicationVO.getGenitourinary()) || 1 == StringUtil.StrTrimInt(complicationVO.getOtherneuropathy())) {
                result.setNeuropathy(true);
            } else {
                result.setNeuropathy(false);
            }
            // 是否视网膜病变
            result.setRetinopathy(1 == StringUtil.StrTrimInt(complicationVO.getRetinopathy()));
            // 是否肾病
            result.setNephropathy(1 == StringUtil.StrTrimInt(complicationVO.getNephropathy()));
        }
    }

    /**
     * 合并症
     *
     * @param patientId
     * @param result
     */
    private void handleComorbidity(Integer patientId, SchemeInputBean result) {
        DtrdEntRdArchiveComorbidity comorbidityVO = comorbidityService.getPatientDiabetesComorbidity(patientId);
        if (null != comorbidityVO) {
            if (1 == StringUtil.StrTrimInt(comorbidityVO.getHypertension()) || 1 == StringUtil.StrTrimInt(comorbidityVO.getHyperlipidemia()) || 1 == StringUtil.StrTrimInt(comorbidityVO.getAngiocardiopathy()) || 1 == StringUtil.StrTrimInt(comorbidityVO.getCerebrovascular()) || 1 == StringUtil.StrTrimInt(comorbidityVO.getPeripheral())) {
                result.setComorbidity(true);
            } else {
                result.setComorbidity(false);
            }
            // 是否高血压病
            result.setHypertension(1 == StringUtil.StrTrimInt(comorbidityVO.getHypertension()));
            // 是否冠心病
            if (1 == StringUtil.StrTrimInt(comorbidityVO.getAngiocardiopathy()) && (StringUtil.StrTrimInt(comorbidityVO.getCoronaryType()) > 0 || !"".equals(StringUtil.StrTrim(comorbidityVO.getCoronaryOther())))) {
                result.setCoronaryDisease(true);
            } else {
                result.setCoronaryDisease(false);
            }
        }
    }

    /**
     * 既往病史
     *
     * @param patientId
     * @param result
     */
    private void handleAnamnesis(Integer patientId, SchemeInputBean result) {
        DtrdEntRdArchiveAnamnesis anamnesisVO = anamnesisService.getPatientAnamnesis(patientId);
        if (null != anamnesisVO) {
            // 低血糖
            result.setBloodSugarLow(1 == StringUtil.StrTrimInt(anamnesisVO.getHypoglycemiaIsExist()));
        }
    }

    /**
     * 处理糖尿病概况
     *
     * @param patientId
     * @param result
     */
    private void handleOverview(Integer patientId, SchemeInputBean result) {
        DtrdEntRdArchiveOverview overviewVO = overviewService.getPatientDiabetesOverview(patientId);
        if (null != overviewVO) {
            if (0 == StringUtil.StrTrimFloat(result.getFbgVal())) {
                result.setFbgVal(StringUtil.StrTrimFloat(overviewVO.getSugarFasting()));
            }
            if (0 == StringUtil.StrTrimFloat(result.getPbgVal())) {
                result.setPbgVal(StringUtil.StrTrimFloat(overviewVO.getSugarBreakfastAfter()));
            }
            if (0 == StringUtil.StrTrimFloat(result.getPbgVal())) {
                result.setPbgVal(StringUtil.StrTrimFloat(overviewVO.getSugarLunchAfter()));
            }
            if (0 == StringUtil.StrTrimFloat(result.getPbgVal())) {
                result.setPbgVal(StringUtil.StrTrimFloat(overviewVO.getSugarSupperAfter()));
            }
            if (0 == StringUtil.StrTrimFloat(result.getHba1c())) {
                result.setHba1c(StringUtil.StrTrimFloat(overviewVO.getHba1c()));
            }
        }
    }

    /**
     * 体格检查表
     *
     * @param patientId
     * @param result
     */
    private void handlePhysicalInfo(Integer patientId, SchemeInputBean result) {
        DtrdEntRdArchivePhysical physicalVO = physicalService.getPatientPhysical(patientId);
        if (null != physicalVO) {
            // 舒张压/低压
            result.setLbpVal(StringUtil.StrTrimFloat(physicalVO.getBloodDiastolicPress()));
            // 收缩压/高压
            result.setHbpVal(StringUtil.StrTrimFloat(physicalVO.getBloodSystolicPress()));
            // 静态心率
            result.setHeartRate(StringUtil.StrTrimInt(physicalVO.getHeartRate()));
        }
    }

    /**
     * 处理查询患者基础信息
     *
     * @param patientId
     * @param result
     */
    private void handleBaseInfo(Integer patientId, SchemeInputBean result) {
        DtrdEntRdArchiveBasic basicVO = basicService.getPatientBasicInfoByPatientId(patientId);
        if (basicVO != null) {
            // 性别、生日、劳动强度
            result.setGender(basicVO.getGender());
            if (basicVO.getBirth() != null) {
                result.setBirth(DateUtils.formatDate(basicVO.getBirth()));
                result.setAge(DateUtil.ageOfNow(basicVO.getBirth()));
            }
            int isSickbed = StringUtil.StrTrimInt(basicVO.getIsSickbed());
            int labourIntensity = StringUtil.StrTrimInt(basicVO.getOccupation());
            if (1 == isSickbed) {
                labourIntensity = 4;
            }
            result.setLabourIntensity(labourIntensity);
            // 身高、体重
            result.setHeight(StringUtil.StrTrimFloat(basicVO.getHeight()));
            result.setWeight(StringUtil.StrTrimFloat(basicVO.getWeight()));
        }
    }

    /**
     * 处理查询实验室检查表信息
     *
     * @param patientId
     * @param result
     */
    private void handleLaboratoryInfo(Integer patientId, SchemeInputBean result) {
        // 实验室检查表
        DtrdEntRdArchiveLaboratory laboratoryVO = laboratoryService.getPatientLaboratory(patientId);
        if (null != laboratoryVO) {
            // 空腹血糖
            result.setFbgVal(StringUtil.StrTrimFloat(laboratoryVO.getSugarFasting()));
            // 餐后血糖
            result.setPbgVal(StringUtil.StrTrimFloat(laboratoryVO.getSugarAfter2()));
            // 糖化血红蛋白
            result.setHba1c(StringUtil.StrTrimFloat(laboratoryVO.getHba1c()));
            // 总胆固醇
            result.setTcVal(StringUtil.StrTrimFloat(laboratoryVO.getTc()));
            // 甘油三酯
            result.setTgVal(StringUtil.StrTrimFloat(laboratoryVO.getTg()));
            // 高密度脂蛋白
            result.setHdlVal(StringUtil.StrTrimFloat(laboratoryVO.getHdlc()));
            // 低密度脂蛋白
            result.setLdlVal(StringUtil.StrTrimFloat(laboratoryVO.getLdlc()));
            // ACR：mg/g
            result.setAcr(StringUtil.StrTrimInt(laboratoryVO.getAcr()));
            // eGFR：ml.min-1.(1.73m2)-1
            result.setEgfr(StringUtil.StrTrimInt(laboratoryVO.getGfr()));
            // 尿蛋白
            result.setUrineProtein(1 == StringUtil.StrTrimInt(laboratoryVO.getUrineProtein()));
        }
    }

    @Override
    public PatientTargetReachStandardAvgRateDaily getPatientTargetReachStandardAvgRateDaily(List<Integer> patientIds) {
        List<DtrdEntRdSigninTargetDetail> targets = CollectionUtil.isNotEmpty(patientIds) ? baseMapper.selectTargetDetailsByPatientId(patientIds) : null;
        if (CollectionUtil.isNotEmpty(targets)) {
            int pgb = 0, pgbSum = 0, fbg = 0, fbgSum = 0, bmi = 0, bmiSum = 0, waist = 0, waistSum = 0, hba1c = 0, hba1cSum = 0;
            PatientTargetReachStandardAvgRateDaily rateDaily = new PatientTargetReachStandardAvgRateDaily();
            for (DtrdEntRdSigninTargetDetail target : targets) {
                Integer projectType = target.getProjectType();
                Constant.TargetProject type = Constant.TargetProject.valueOf(projectType);
                if (target.getValue() != null && target.getTargetHigh() != null) {
                    switch (type) {
                        case PBG:
                            pgbSum++;
                            if (target.getValue() <= target.getTargetHigh()) {
                                pgb++;
                            }
                            break;
                        case FBG:
                            fbgSum++;
                            if (target.getValue() <= target.getTargetHigh()) {
                                fbg++;
                            }
                            break;
                        case BMI:
                            bmiSum++;
                            if (target.getValue() <= target.getTargetHigh()) {
                                bmi++;
                            }
                            break;
                        case WAIST:
                            waistSum++;
                            if (target.getValue() <= target.getTargetHigh()) {
                                waist++;
                            }
                            break;
                        case HBA1C:
                            hba1cSum++;
                            if (target.getValue() <= target.getTargetHigh()) {
                                hba1c++;
                            }
                            break;
                    }
                }
            }
            // 设置值
            if (pgbSum != 0) {
                rateDaily.setPbg(pgb * 100 / pgbSum);
            }
            if (fbgSum != 0) {
                rateDaily.setFbg(fbg * 100 / fbgSum);
            }
            if (bmiSum != 0) {
                rateDaily.setBmi(bmi * 100 / bmiSum);
            }
            if (waistSum != 0) {
                rateDaily.setWaist(waist * 100 / waistSum);
            }
            if (hba1cSum != 0) {
                rateDaily.setHba1c(hba1c * 100 / hba1cSum);
            }
            return rateDaily;
        }
        return null;
    }

    @Override
    public List<Integer> getPatientTargetIds(Integer patientId, String startDate, String endDate) {
        return baseMapper.selectPatientTargetIds(patientId, startDate, endDate);
    }

    @Override
    public List<DtrdEntRdSigninTarget> getLatestTargets() {
        LambdaQueryWrapper<DtrdEntRdSigninTarget> wrapper = Wrappers.lambdaQuery(DtrdEntRdSigninTarget.class).eq(DtrdEntRdSigninTarget::getCurrentStatus, Constant.TargetUsageStatus.USING.getType());
        return list(wrapper);
    }

    @Override
    public Integer getPatientFirstTargetId(Integer patientId) {
        LambdaQueryWrapper<DtrdEntRdSigninTarget> wrapper = Wrappers.lambdaQuery(DtrdEntRdSigninTarget.class).eq(DtrdEntRdSigninTarget::getPatientId, patientId).orderByAsc(DtrdEntRdSigninTarget::getCreateTime).last("limit 1");
        DtrdEntRdSigninTarget target = getOne(wrapper);
        return Optional.ofNullable(target).map(DtrdEntRdSigninTarget::getDataId).orElse(null);
    }

    @Override
    public DtrdEntRdSigninTarget getPatientLastTargetId(Integer patientId, String endDate) {
        // 获取控制目标报告，获取结束时间前最新的报告即可
        LambdaQueryWrapper<DtrdEntRdSigninTarget> queryWrapperSigninTarget = Wrappers.lambdaQuery(DtrdEntRdSigninTarget.class)
                .eq(DtrdEntRdSigninTarget::getIsDel, 0)
//                获取结束时间前最后创建的控制目标
                .le(DtrdEntRdSigninTarget::getCreateTime, endDate)
                .eq(DtrdEntRdSigninTarget::getPatientId, patientId)
                .orderByDesc(DtrdEntRdSigninTarget::getCreateTime)
                .last("limit 1");
        return getOne(queryWrapperSigninTarget);
    }

    @Override
    public String getFirstTargetName(Integer patientId) {
        Integer targetId = getPatientFirstTargetId(patientId);
        if (targetId != null) {
            DtrdEntRdSigninTarget target = getById(targetId);
            return Optional.ofNullable(target).map(DtrdEntRdSigninTarget::getTargetName).orElse(null);
        }
        return null;
    }

    @Override
    public IPage<TargetInfo> pageTarget(TargetPageRequest request) {
        Integer patientId = request.getPatientId();
        LambdaQueryWrapper<DtrdEntRdSigninTarget> queryWrapper = Wrappers.lambdaQuery(DtrdEntRdSigninTarget.class).eq(DtrdEntRdSigninTarget::getPatientId, patientId).orderByDesc(DtrdEntRdSigninTarget::getCreateTime);
        Page<DtrdEntRdSigninTarget> page = new Page<>(request.getPageNum(), request.getPageSize());
        page = page(page, queryWrapper);
        return page.convert(po -> new TargetInfo().parseFromPo(po));
    }

    private void changeLatestTargetStatus(Integer patientId) {
        LambdaQueryWrapper<DtrdEntRdSigninTarget> wrapper = Wrappers.lambdaQuery(DtrdEntRdSigninTarget.class).eq(DtrdEntRdSigninTarget::getPatientId, patientId).eq(DtrdEntRdSigninTarget::getCurrentStatus, Constant.TargetStatus.USING.getType());
        DtrdEntRdSigninTarget latestRecord = getOne(wrapper);
        if (latestRecord == null) {
            return;
        }
        latestRecord.setCurrentStatus(Constant.TargetStatus.UNUSED.getType());
        updateById(latestRecord);
    }

    @Override
    public TargetAndDetailInfo getTargetAndDetailsInfo(Integer targetId) {
        TargetAndDetailInfo info = new TargetAndDetailInfo();
        DtrdEntRdSigninTarget target = getById(targetId);
        info.parseFromPo(target);
        LambdaQueryWrapper<DtrdEntRdSigninTargetDetail> queryWrapper = Wrappers.lambdaQuery(DtrdEntRdSigninTargetDetail.class).eq(DtrdEntRdSigninTargetDetail::getTargetId, targetId);
        List<DtrdEntRdSigninTargetDetail> details = targetDetailService.list(queryWrapper);
        info.parseFromPo(details);
        return info;
    }

    @Override
    public TargetAndDetailInfo getLastTargetAndDetailsInfo(Integer patientId) {
        DtrdEntRdSigninTarget target = baseMapper.getLastTargetInfo(patientId);
        TargetAndDetailInfo info = null;
        if (target != null) {
            info = new TargetAndDetailInfo();
            info.parseFromPo(target);
            List<DtrdEntRdSigninTargetDetail> details = targetDetailService.getTargetDetailList(target.getDataId());
            if (CheckUtil.isNotEmpty(details)) {
                info.parseFromPo(details);
            }
        }
        return info;
    }

    private LambdaQueryWrapper<DtrdEntRdSigninTarget> getBaseWrapper() {
        return Wrappers.lambdaQuery(DtrdEntRdSigninTarget.class).eq(DtrdEntRdSigninTarget::getIsDel, 0);
    }
}




